#ifndef __MYTHREAD_HPP__
#define __MYTHREAD_HPP__

#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>//用于使用syscall这个软中断
#include "Logger.hpp"


#define get_lwp_id() syscall(SYS_gettid)//syscall陷入内核，进行系统调用，
//SYS_gettid是系统调用号，之前说过内核调用系统调用是通过系统调用号进行调用的，作用就是拿到线程的id(tid)，也就是我们说的lwp
//想要拿到lwp我们在用户层面是做不到的，要使用软中断

using func_t = std::function<void(const std::string& name)>;
#define ThreadNameDefault "None_Name"

class Thread
{
public:
    Thread(func_t func, std::string thread_name = ThreadNameDefault)
        :_thread_name(thread_name)
        ,_func(func)
        ,_isrunning(false)
    {
        std::cout << "构造函数调用成功，线程名字为：" << _thread_name << std::endl;
    }

    static void* start_routine(void* args)//加上static就可以忽略this指针，不然就变成了两个参数，这样pthread_creat调用就会出问题
    {
        Thread* self = static_cast<Thread*>(args);
        self->_isrunning = true;
        self->_lwp_id = get_lwp_id();
        //std::cout << "DEBUG:准备进入func函数" << std::endl;
        self->_func(self->_thread_name);
        //std::cout << "DEBUG:func函数调用完毕" << std::endl;
        pthread_exit((void*)0);
    }

    void Start()    
    {
        int n = pthread_create(&_tid, nullptr, start_routine, this);
        if(n == 0)
        {
            LOG(Loglevel::INFO) << _thread_name << " running success";
        }
    }
    void Join()
    {
        if(!_isrunning)
        {
            return;
        }
        void* thread_return;
        int n = pthread_join(_tid, &thread_return);
        if(n == 0)
        {
            LOG(Loglevel::INFO) << _thread_name << " pthread_join success";
        }
    }

    ~Thread()
    {
        
    }
private:
    std::string _thread_name;
    pthread_t _tid;//这里的tid跟上面注释中不同，这么命名是为了方便，他其实是struct pthread的起始虚拟地址（内核线程ID为TID，这里的为POSIX线程的ID） 
    pid_t _lwp_id;
    bool _isrunning;
    func_t _func;
};


#endif